package cn.miao.hrm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.text.StrSplitter;
import cn.miao.client.CourseESFeginClient;
import cn.miao.constant.BaseConst;
import cn.miao.context.LoginContext;
import cn.miao.doc.CourseDoc;
import cn.miao.exception.MiaoRuntimeException;
import cn.miao.hrm.domain.*;
import cn.miao.hrm.dto.SaveCourseDto;
import cn.miao.hrm.mapper.CourseMapper;
import cn.miao.hrm.mapper.CourseTypeMapper;
import cn.miao.hrm.service.ICourseDetailService;
import cn.miao.hrm.service.ICourseMarketService;
import cn.miao.hrm.service.ICourseService;
import cn.miao.to.EmailTo;
import cn.miao.to.MessageTo;
import cn.miao.to.SMSTo;
import cn.miao.util.AjaxResult;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

import static cn.miao.constants.MQConstant.EXCHANGE_NAME_TOPIC;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author MiaoDaWei
 * @since 2021-11-26
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {

    @Autowired
    private ICourseDetailService courseDetailService;
    @Autowired
    private ICourseMarketService courseMarketService;
    @Autowired
    private CourseTypeMapper courseTypeMapper;
    @Autowired
    private CourseESFeginClient courseESFeginClient;
    @Autowired
    private RabbitTemplate rabbitTemplate;


    /**
     * 保存课程
     *
     * @param courseDto 当然dto
     * @return {@link AjaxResult}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult saveCourse(SaveCourseDto courseDto) {
        //获取当前用户信息
        Login login = LoginContext.getLogin();
        Assert.notNull(login, "当前登录用户无效!");


        Course course = courseDto.getCourse();
        CourseDetail courseDetail = courseDto.getCourseDetail();
        CourseMarket courseMarket = courseDto.getCourseMarket();
        //该课程是否存在重复课程
        EntityWrapper<Course> courseWrapper = new EntityWrapper<>();
        courseWrapper.eq("name", course.getName());
        Course nullCourse = this.selectOne(courseWrapper);
        Assert.isNull(nullCourse, "该课程名称已存在,请勿重复添加!");

        Date currentDate = new Date();
        //开课时间必须大于当前时间
        if (currentDate.after(course.getStartTime())) {
            throw new MiaoRuntimeException("开课时间必须大于当前时间!");
        }
        //开课时间不能小于结课时间
        if (course.getStartTime().after(course.getEndTime())) {
            throw new MiaoRuntimeException("开课时间不能小于结课时间");
        }
        //如果收费规则为收费,那么课程价格和课程原价就不能为空!
        if (courseMarket.getCharge().compareTo(BaseConst.CourseState.COURSE_MARKET_CHARGE_TOLL) == BaseConst.ZERO) {
            Assert.notNull(courseMarket.getPrice(), "请输入价格!");
            Assert.notNull(courseMarket.getPriceOld(), "请输入原价!");
        }

        //保存课程
        course.setStatus(BaseConst.CourseState.COURSE_STATE_DOWN);
        course.setTenantId(login.getTenantId());
        course.setTenantName(login.getTenantName());
        //这里登录userid 其实就是当前登录的id-loginid
        course.setUserId(login.getId());
        course.setUserName(login.getUsername());
        course.setOfflineTime(currentDate);
        this.insert(course);

        //保存课程详情
        courseDetail.setId(course.getId());
        courseDetailService.insert(courseDetail);

        //保存课程营销表
        courseMarket.setId(course.getId());
        courseMarketService.insert(courseMarket);

        //修改课程类型中的课程数量
        CourseType courseType = new CourseType();
        courseType.setId(course.getCourseTypeId());
        CourseType selectOne = courseTypeMapper.selectOne(courseType);
        List<String> split = StrSplitter.split(selectOne.getPath(), ".", 0, true, true);
        courseTypeMapper.updateBatchByIds(1, split);

        return AjaxResult.me();
    }

    /**
     * 上线课程
     *
     * @param id id
     * @return {@link AjaxResult}
     */
    @Override
    public AjaxResult onLineCourse(Long id) {
        //查询课程是否存在或是处于下线的状态
        Course course = this.selectById(id);
        Assert.notNull(course, "该课程不存在,请重新再试!");
        Assert.isTrue(course.getStatus().compareTo(BaseConst.CourseState.COURSE_STATE_DOWN) == BaseConst.ZERO, "课程已处于上线状态,请勿重复上线!");

        //修改为上线状态
        course.setStatus(BaseConst.CourseState.COURSE_STATE_UP);
        this.updateById(course);

        //添加进ES中,方便后续的查询!
        CourseType courseType = courseTypeMapper.selectById(course.getCourseTypeId());

        CourseMarket courseMarket = courseMarketService.selectById(course.getId());
        CourseDoc doc = BeanUtil.copyProperties(course, CourseDoc.class);
        doc.setChargeName(courseMarket.getCharge().equals(1) ? "免费" : "收费");
        doc.setPrice(courseMarket.getPrice());
        doc.setPriceOld(courseMarket.getPriceOld());
        doc.setCourseTypeId(Convert.toInt(course.getCourseTypeId()));
        doc.setCourseTypeName(courseType.getName());
        AjaxResult result = courseESFeginClient.save(doc);

        Assert.isTrue(result.isSuccess(), "上线课程失败!");

        //课程上线-发布消息
        this.publishMessage(course);
        return AjaxResult.me();
    }

    /**
     * 发布消息
     */
    private void publishMessage(Course course){
        EmailTo emailTo = new EmailTo().setId(Convert.toInt(course.getId())).setCourseName(course.getName()).setEmails(Arrays.asList("2439135122@qq.com", "xxxx@qq.com")).setOnlineTime(course.getOnlineTime());
        //发送邮件
        rabbitTemplate.convertAndSend(EXCHANGE_NAME_TOPIC,"course.email",emailTo);
        SMSTo smsTo = new SMSTo().setId(Convert.toInt(course.getId())).setCourseName(course.getName()).setSmss(Arrays.asList("15882688721", "18380223696")).setOnlineTime(course.getOnlineTime());
        //发送短信
        rabbitTemplate.convertAndSend(EXCHANGE_NAME_TOPIC,"course.sms",smsTo);
        MessageTo message = new MessageTo().setId(Convert.toInt(course.getId())).setCourseName(course.getName()).setMessages(Arrays.asList("张三", "李四")).setOnlineTime(course.getOnlineTime());
        //发送站内信
        rabbitTemplate.convertAndSend(EXCHANGE_NAME_TOPIC,"course.message",message);
    }


    /**
     * 下线
     *
     * @param id id
     * @return {@link AjaxResult}
     */
    @Override
    public AjaxResult offLineCourse(Long id) {
        //查询课程是否存在或是处于下线的状态
        Course course = this.selectById(id);
        Assert.notNull(course, "该课程不存在,请重新再试!");
        Assert.isTrue(course.getStatus().compareTo(BaseConst.CourseState.COURSE_STATE_UP) == BaseConst.ZERO, "课程已处于下线状态,请勿重复操作!");

        //修改为下线状态
        course.setStatus(BaseConst.CourseState.COURSE_STATE_DOWN);
        this.updateById(course);

        AjaxResult remove = courseESFeginClient.remove(id);
        Assert.isTrue(remove.isSuccess(), "下线课程失败!");

        return AjaxResult.me();
    }

}
